import { Component, OnInit } from '@angular/core';
import {FormGroup, FormControl, FormBuilder, FormArray} from '@angular/forms';
import {CommonService} from './../shared/service/common.service';
import { forbiddenNameValidator } from './../shared/directive/forbidden-name.directive';

@Component({
  selector: 'app-abstract-control',
  templateUrl: './abstract-control.component.html',
  styleUrls: ['./abstract-control.component.scss']
})
export class AbstractControlComponent implements OnInit {

  // 表单初始化
  profileForm = new FormGroup({
    firstName: new FormControl(''),
    lastName: new FormControl(''),
    address: new FormGroup({
      street: new FormControl(''),
      city: new FormControl(''),
      state: new FormControl('')
    }),
    information: new FormGroup({
      height: new FormControl({value: '', disabled: true}),
      age: new FormControl({value: '', disabled: false}),
      gender: new FormControl({value: '', disabled: true})
    }),
    aliases: this.fb.array([
      new FormControl('')
    ])
  });

  // 下拉选择框的数据列表
  dropdownDataList = {
    formGroup: ['profileForm'],
    formControl: [{
      title: 'profileForm',
      key: 'profileForm',
      selectable: false,
      children: []
    }],
    formArray: []
  };

  // 默认展开树节点
  expandKeys = ['profileForm'];

  // 选中的表单类型字符串
  selectedFormStr = {
    formGroup: 'profileForm',
    formControl: 'firstName',
    formArray: 'aliases'
  };

  // 选中的表单类型对象
  selectedFormObj = {
    formGroup: null,
    formControl: null,
    formArray: null
  };

  attrOutput: string = '';
  methodOutput: string = '';

  get aliases() {
    return this.profileForm.get('aliases') as FormArray;
  }

  constructor(
    private fb: FormBuilder,
    private commonService: CommonService
  ) { }

  ngOnInit() {
    this.createFormTree(this.profileForm.controls, this.dropdownDataList['formControl'][0]['children']);
    for (const key of Object.keys(this.selectedFormStr)) {
      this.getFormNodeInstance(key, this.selectedFormStr[key]);
    }
  }

  // 生成form表单的树状结构
  createFormTree(controls, children) {
    for (const key of Object.keys(controls)) {
      const childNode = controls[key];
      const treeObj = {
        title: key,
        key
      };
      if (childNode['controls']) {
        this.dropdownDataList['formGroup'].push(key);

        if (childNode instanceof FormGroup) {
          treeObj['selectable'] = false;
          treeObj['children'] = [];
          children.push(treeObj);
          this.expandKeys.push(key);
          this.createFormTree(childNode['controls'], children[children.length - 1]['children']);
        }
      } else {
        treeObj['isLeaf'] = true;
        children.push(treeObj);
      }
    }
  }

  /**
   * 获取表单子元素实例
   * @param type(string) ：类型， 有三种： FormGroup、FormControl、FormArray
   * @param name(string) ：名称
   * @param formGroup(FormGroup) ：当前的FormGroup，在递归循环时使用它来获取子控件
   */
  getFormNodeInstance(type, name, formGroup: FormGroup = this.profileForm) {
    if (name === 'profileForm') {
      this.selectedFormObj[type] = this.profileForm;
    } else {
      if (formGroup.get(name)) {
        this.selectedFormObj[type] = formGroup.get(name);
      } else {
        const controls = formGroup.controls;
        for (const key of Object.keys(controls)) {
          const childNode = controls[key];
          if (childNode instanceof FormGroup) {
            this.getFormNodeInstance(type, name, childNode);
          }
        }
      }
    }
  }

  addAlias() {
    this.aliases.push(new FormControl(''));
    const aliasesLength = this.aliases.controls.length - 1;
    this.dropdownDataList['formControl'][0]['children'][4]['children'].push({
      title: 'Alias' + aliasesLength,
      key: 'alias' + aliasesLength,
      isLeaf: true
    });
  }

  // 监听FormGroup下拉框变化
  handleFormGroupChange(name) {
    this.getFormNodeInstance('formGroup', name);
  }

  // 监听FormControl下拉框变化
  handleFormControlChange(name) {
    this.getFormNodeInstance('formControl', name);
  }

  /**
   * 获取FormGroup的value值
   */
  getFormGroupValue() {
    this.attrOutput = this.selectedFormStr['formGroup'] + '控件的value值为： ' + this.commonService.convertType(this.selectedFormObj['formGroup'].value);
  }

  /**
   * 获取FormControl的value值
   */
  getFormControlValue() {
    this.attrOutput = this.selectedFormStr['formControl'] + '控件的value值为： ' + this.commonService.convertType(this.selectedFormObj['formControl'].value);
  }

  /**
   * 获取FormArray的value值
   */
  getFormArrayValue() {
    this.attrOutput = this.selectedFormStr['formArray'] + '的value值为： ' + this.commonService.convertType(this.selectedFormObj['formArray'].value);
  }

  /**
   * 获取父控件
   */
  getParentControl() {
    this.attrOutput = '请打开控制台查看输出信息';
    console.log(name + '的父控件是： ');
    console.log(this.selectedFormObj['formControl'].parent);
  }

  /**
   * 获取FormControl的同步校验器
   */
  getFormControlValidator() {
    this.attrOutput = this.selectedFormStr['formControl'] + '的同步校验器函数为： \n' + this.commonService.convertType(this.selectedFormObj['formControl'].validator);
  }

  /**
   * 获取FormGroup控件的valid值
   */
  getFormGroupValid() {
    this.attrOutput = this.selectedFormStr['formGroup'] + '的valid值为： ' + this.selectedFormObj['formGroup'].valid;
  }

  /**
   * 获取FormControl控件的valid值
   */
  getFormControlValid() {
    this.attrOutput = this.selectedFormStr['formControl'] + '的valid值为： ' + this.selectedFormObj['formControl'].valid;
  }

  /**
   * 获取FormGroup控件的invalid值
   */
  getFormGroupInValid() {
    this.attrOutput = this.selectedFormStr['formGroup'] + '的invalid值为： ' + this.selectedFormObj['formGroup'].invalid;
  }

  /**
   * 获取FormControl控件的invalid值
   */
  getFormControlInValid() {
    this.attrOutput = this.selectedFormStr['formControl'] + '的invalid值为： ' + this.selectedFormObj['formControl'].invalid;
  }


  /* 以下是方法列表 */
  /**
   * 设置FormGroup控件的同步校验器
   */
  setFormGroupValidators() {
    // this.selectedFormObj['FormGroup'].setValidators(forbiddenNameValidator(/sowhat/i));
  }

  /**
   * 设置FormControl控件的同步校验器
   */
  setFormControlValidators(regExp) {
    this.selectedFormObj['formControl'].setValidators(forbiddenNameValidator(eval(regExp)));
    this.methodOutput = '设置成功，请在' + this.selectedFormStr['formControl'] + '输入框尝试';
  }

  /**
   * 设置FormControl的value值
   */
  setFormControlValue(value) {
    this.selectedFormObj['formControl'].setValue(value);
    this.methodOutput = '设置成功，请在' + this.selectedFormStr['formControl'] + '输入框查看value值';
  }
}
